/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <time.h>

#include "Utils.h"
#include "Room.h"
#include "MudPlayer.h"
#include "CmdVisitor.h"
#include "config.h"

using namespace Chronos;
using namespace std;

int Utils::roll(unsigned int min, unsigned int max) {
    if (min == max) return min;
    return (random() % (max+1-min)) + min;
}


char* Utils::itoa(int value) {
    static char str[12];
	if (value >= 0) return Utils::itoa((unsigned int)value);

	char* number = Utils::itoa((unsigned int)(-value));
	str[0] = '-';
	strcpy(&str[1], number);
	return str;
}


char* Utils::itoa(unsigned int value) {
    static char str[11];
    str[10] = '\0';
    int  pos = 9;
    do {
        str[pos--] = (char) ((value % 10) + 0x30);
        value /= 10;
    } while (value != 0);
    return str + pos + 1;
}


std::string Utils::itos(unsigned int value) {
    return (string)itoa(value);
}


#define LF 10
#define CR 13
int Utils::stripNewline(char* buf) {
    char* current = buf;
    while(*current != 0) {
        if (*current == LF || *current == CR) {
            *current = 0;
            break;
        }
        ++current;
    }
    return (current - buf);
}


static int uniqueKeyID = 0;

int Utils::getUniqueKeyID() {
    return uniqueKeyID++;
}


const char* Utils::getTime() {
    static char buffer[10];
    time_t now = time(0);
    struct tm* now2 = localtime(&now);
    sprintf(buffer, "%02d:%02d:%02d", now2->tm_hour, now2->tm_min, now2->tm_sec);
    return buffer;
}


const char* Utils::getDate() {
    static char buffer[40];
    time_t now = time(0);
    struct tm* now2 = localtime(&now);
    //sprintf(buffer, "%04d:%02d:%02d", now2->tm_year, now2->tm_mon, now2->tm_mday);
    sprintf(buffer, "%s", asctime(now2));
    return buffer;
}


unsigned int pulse = 0;

unsigned int Utils::getPulse() { return pulse; }

void Utils::nextPulse() { ++pulse; }

unsigned int Utils::getUptime() {
    return pulse / seconds(1);
}

#define SEC_PER_MIN (60)
#define SEC_PER_HOUR (60*SEC_PER_MIN)
#define SEC_PER_DAY (24*SEC_PER_HOUR)

const char* Utils::toDurationString(unsigned int ticks) {
    static char buffer[16];
    unsigned int seconds = ticks / Config::PULSE_PER_SEC;
    unsigned int days = seconds / SEC_PER_DAY;
    seconds -= days * SEC_PER_DAY;
    unsigned int hours = seconds / SEC_PER_HOUR;
    seconds -= hours * SEC_PER_HOUR;
    unsigned int minutes = seconds / SEC_PER_MIN;
    seconds -= minutes * SEC_PER_MIN;
    snprintf(buffer, 15, "%ud%uh%um%us", days, hours, minutes, seconds);
    return buffer;
}

